package com.tuling.code.cglib;

import org.junit.Test;
import org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor;
import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.framework.AdvisedSupport;
import org.springframework.aop.framework.AopProxy;
import org.springframework.aop.framework.DefaultAopProxyFactory;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;

import com.tuling.code.service.UserService;
import com.tuling.code.service.impl.UserServiceImpl;

/**
 * Spring Aop tester
 * @author lenovo
 *
 */
public class CglibTester {
	
	/**
	 * 代理对象创建
	 */
	@Test
	public void createProxyTest(){
		Object target = new UserServiceImpl();
		ProxyFactory pf = new ProxyFactory(target);
		pf.addAdvice(new CountingBeforeAdvice());
		UserService service = (UserService) pf.getProxy();
		service.save();
		service.save();
		service.save();
	}
	
	//添加多次advice
	@Test
	public void createProxyTest2(){
		Object target = new UserServiceImpl();
		ProxyFactory pf = new ProxyFactory(target);
		CountingBeforeAdvice advice = new CountingBeforeAdvice();
		pf.addAdvice(advice);
		pf.addAdvice(advice);
		UserService service = (UserService) pf.getProxy();
		service.save();
	}
	
	//AspectJProxyFactory
	@Test
	public void createProxyAspectJByTest(){
		Object target = new UserServiceImpl();
		AspectJProxyFactory pf = new AspectJProxyFactory(target);
		AspectJExpressionPointcutAdvisor advisor = new AspectJExpressionPointcutAdvisor();
		advisor.setExpression("execution(* *.getUser(..))");
		CountingBeforeAdvice advice = new CountingBeforeAdvice();
		advisor.setAdvice(advice);
		pf.addAdvisor(advisor);
		
		UserService service = (UserService) pf.getProxy();
		service.save();
		service.getUser("1001");
	}
	
	
	/**
	 * Advised  
	 * Advice   通知，不会告知具体在哪里执行，执行所有的
	 * Advisor  通知+Pointcut（组合适配）  哪个类哪个方法需要执行      通知和拦截点是配的一个地方 
	 */
	//动态添加和移除advice
	@Test
	public void dynamicAddAndRemoveAdviceTest(){
		Object target = new UserServiceImpl();
		ProxyFactory pf = new ProxyFactory(target);
		UserService service = (UserService) pf.getProxy();
		service.save();
		
		Advised advised = (Advised) service;
		
		//Advice a;
		
		advised.addAdvice(new CountingBeforeAdvice());
		advised.addAdvice(new CountingAfterReturningAdvice());
		
		service.getUser("1001");
		System.out.println("\n-------------------------\n");
		service.getUser("1002");
		System.out.println("\n-------------------------\n");
		service.getUser("1002");
	}
	
	@Test
	public void createProxyFactory(){
		Object target = new UserServiceImpl();
		DefaultAopProxyFactory factory = new DefaultAopProxyFactory();
		CountingBeforeAdvice advice = new CountingBeforeAdvice();
		AdvisedSupport config = new AdvisedSupport();
		config.setTarget(target);
		
		DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
		//方式一
		advisor.setAdvice(advice);
		config.addAdvisor(advisor);
		
		//方式二
		config.addAdvice(advice);
		
		//重点：JDKDynamicProxy || ObjenesisCglibAopProxy
		AopProxy proxy = factory.createAopProxy(config);
		UserService service = (UserService) proxy.getProxy();
		service.getUser("1001");
		
	}
}